package com.mindskip.xzs.controller.admin;
//前端调用`/api/admin/user/page/list`接口获取用户列表，用于显示在用户管理页面上。
//返回的数据包括用户的详细信息，比如用户名、密码（解密后）、生日、年龄等。
//前端调用`/api/admin/user/student/list`接口获取学生列表，用于显示在学生管理页面或下拉菜单中。
//返回的数据是学生用户的详细列表。
//分页获取用户事件日志列表
//前端调用`/api/admin/user/event/page/list`接口获取用户事件日志，用于显示在用户活动日志页面上。
//返回的数据包括用户的活动日志信息，比如创建时间、事件类型等。
//根据ID获取用户信息
//前端调用`/api/admin/user/select/{id}`接口获取特定用户的信息，用于用户详情页面或编辑页面。
//返回的数据是指定用户的详细信息，包含解密后的密码。
//获取当前用户信息
//前端调用`/api/admin/user/current`接口获取当前登录用户的信息，用于显示在个人信息页面。
//返回的数据是当前用户的详细信息。
//编辑用户信息
//前端调用`/api/admin/user/edit`接口提交用户信息，用于添加新用户或更新现有用户的信息。
//如果是添加新用户，前端需要确保用户名唯一且密码不为空。
//返回的数据是保存后的用户信息。
//更新当前用户信息
//前端调用`/api/admin/user/update`接口提交当前用户的更新信息，用于更新用户的个人信息。
//返回的状态表示更新操作是否成功。
//修改用户状态
//前端调用`/api/admin/user/changeStatus/{id}`接口切换用户的启用/禁用状态，用于用户的状态管理。
//返回的新状态用于前端更新用户状态显示。
//删除用户
//前端调用`/api/admin/user/delete/{id}`接口删除指定用户，用于用户管理的删除操作。
//返回的状态表示删除操作是否成功。
//根据用户名查询用户
//前端调用`/api/admin/user/selectByUserName`接口根据用户名查询用户，用于搜索功能。
//返回的数据是匹配用户名的用户列表，用于前端展示搜索结果。

//使用`@Autowired`和`@Resource`注解注入所需的服务类（如UserService、UserEventLogService等），方便在控制器中调用这些服务的方法。
//调用`userService.userPage`方法获取分页用户数据。
//使用`PageInfoHelper.copyMap`方法将用户数据转换为响应模型，并解密用户密码，计算用户年龄。
//调用`userService.getStudentList`方法获取学生列表。
//调用`userEventLogService.page`方法获取分页用户事件日志数据。
//使用`PageInfoHelper.copyMap`方法将日志数据转换为响应模型，并格式化创建时间。
//调用`userService.getUserById`方法获取用户信息。
//解密用户密码并返回用户信息。
//调用`getCurrentUser`方法获取当前用户信息，并返回响应模型。
//新用户创建时，检查用户名是否存在，密码是否为空。
//将`UserCreateVM`对象映射为`User`对象，处理生日为空情况。
//新用户和更新用户分别处理，设置相应的用户信息（如密码加密、时间设置等）。
//获取当前用户并映射更新信息，更新用户信息。
//获取用户信息并切换状态（启用/禁用），更新用户信息。
//获取用户信息并设置删除标志，更新用户信息。
//调用`userService.selectByUserName`方法根据用户名查询用户，返回匹配的用户列表。

import com.github.pagehelper.PageInfo;
import com.mindskip.xzs.base.BaseApiController;
import com.mindskip.xzs.base.RestResponse;
import com.mindskip.xzs.configuration.property.SystemConfig;
import com.mindskip.xzs.domain.User;
import com.mindskip.xzs.domain.UserEventLog;
import com.mindskip.xzs.domain.enums.UserStatusEnum;
import com.mindskip.xzs.domain.other.KeyValue;
import com.mindskip.xzs.service.AuthenticationService;
import com.mindskip.xzs.service.BatchUserServer;
import com.mindskip.xzs.service.UserEventLogService;
import com.mindskip.xzs.service.UserService;
import com.mindskip.xzs.utility.DateTimeUtil;
import com.mindskip.xzs.utility.PageInfoHelper;
import com.mindskip.xzs.utility.RsaUtil;
import com.mindskip.xzs.viewmodel.admin.user.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;


@RestController("AdminUserController")
@RequestMapping(value = "/api/admin/user")
public class UserController extends BaseApiController {

    // 自动注入服务类
    private final UserService userService;
    private final UserEventLogService userEventLogService;
    private final AuthenticationService authenticationService;
    private final SystemConfig systemConfig;

    // 构造函数，使用@Autowired注解自动注入依赖
    @Autowired
    public UserController(UserService userService, UserEventLogService userEventLogService, AuthenticationService authenticationService, SystemConfig systemConfig) {
        this.userService = userService;
        this.userEventLogService = userEventLogService;
        this.authenticationService = authenticationService;
        this.systemConfig =systemConfig;
    }

    // 使用@Resource注解注入BatchUserServer实例
    @Resource
    private BatchUserServer batchUserServer;

    // 分页获取用户列表
    @RequestMapping(value = "/page/list", method = RequestMethod.POST)
    public RestResponse<PageInfo<UserResponseVM>> pageList(@RequestBody UserPageRequestVM model) {
        // 调用userService获取分页用户数据
        PageInfo<User> pageInfo = userService.userPage(model);
        // 将User对象转换为UserResponseVM对象
        PageInfo<UserResponseVM> page = PageInfoHelper.copyMap(pageInfo, UserResponseVM::from);
        // 解密用户密码并计算年龄
        for(int i=0;i<page.getList().size();i++){
            page.getList().get(i).setPassword(RsaUtil.rsaDecode(systemConfig.getPwdKey().getPrivateKey(),page.getList().get(i).getPassword()));
            if(!Objects.equals(page.getList().get(i).getBirthDay(), "")) {
                page.getList().get(i).setAge(getAgeByBirth(DateTimeUtil.parse(page.getList().get(i).getBirthDay(), DateTimeUtil.STANDER_FORMAT)));
            }
        }
        return RestResponse.ok(page);
    }

    // 获取学生列表
    @RequestMapping(value = "student/list", method = RequestMethod.GET)
    public  RestResponse studentList(){
        // 调用userService获取学生列表
        List<User> users=userService.getStudentList();
        return RestResponse.ok(users);
    }

    // 分页获取用户事件日志列表
    @RequestMapping(value = "/event/page/list", method = RequestMethod.POST)
    public RestResponse<PageInfo<UserEventLogVM>> eventPageList(@RequestBody UserEventPageRequestVM model) {
        // 调用userEventLogService获取分页用户事件日志数据
        PageInfo<UserEventLog> pageInfo = userEventLogService.page(model);
        // 将UserEventLog对象转换为UserEventLogVM对象
        PageInfo<UserEventLogVM> page = PageInfoHelper.copyMap(pageInfo, d -> {
            UserEventLogVM vm = modelMapper.map(d, UserEventLogVM.class);
            vm.setCreateTime(DateTimeUtil.dateFormat(d.getCreateTime()));
            return vm;
        });
        return RestResponse.ok(page);
    }

    // 根据ID获取用户信息
    @RequestMapping(value = "/select/{id}", method = RequestMethod.POST)
    public RestResponse<UserResponseVM> select(@PathVariable Integer id) {
        // 调用userService获取用户信息
        User user = userService.getUserById(id);
        UserResponseVM userVm = UserResponseVM.from(user);
        // 解密用户密码
        userVm.setPassword(RsaUtil.rsaDecode(systemConfig.getPwdKey().getPrivateKey(), user.getPassword()));
        return RestResponse.ok(userVm);
    }

    // 获取当前用户信息
    @RequestMapping(value = "/current", method = RequestMethod.POST)
    public RestResponse<UserResponseVM> current() {
        // 调用基类方法获取当前用户
        User user = getCurrentUser();
        UserResponseVM userVm = UserResponseVM.from(user);
        return RestResponse.ok(userVm);
    }

    // 编辑用户信息
    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    public RestResponse<User> edit(@RequestBody @Valid UserCreateVM model) {
        // 创建新用户时进行校验
        if (model.getId() == null) {
            User existUser = userService.getUserByUserName(model.getUserName());
            if (null != existUser) {
                return new RestResponse<>(2, "用户已存在");
            }
            if (StringUtils.isBlank(model.getPassword())) {
                return new RestResponse<>(3, "密码不能为空");
            }
        }

        // 处理生日为空的情况
        if (StringUtils.isBlank(model.getBirthDay())) {
            model.setBirthDay(null);
        }

        // 将UserCreateVM对象映射为User对象
        User user = modelMapper.map(model, User.class);

        // 创建新用户
        if (model.getId() == null) {
            String encodePwd = authenticationService.pwdEncode(model.getPassword());
            user.setPassword(encodePwd);
            user.setUserUuid(UUID.randomUUID().toString());
            user.setCreateTime(new Date());
            user.setLastActiveTime(new Date());
            user.setDeleted(false);
            userService.insertByFilter(user);
        } else {
            // 更新用户信息
            if (!StringUtils.isBlank(model.getPassword())) {
                String encodePwd = authenticationService.pwdEncode(model.getPassword());
                user.setPassword(encodePwd);
            }
            user.setModifyTime(new Date());
            userService.updateByIdFilter(user);
        }
        return RestResponse.ok(user);
    }

    // 更新当前用户信息
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public RestResponse update(@RequestBody @Valid UserUpdateVM model) {
        // 获取当前用户
        User user = userService.selectById(getCurrentUser().getId());
        // 将UserUpdateVM对象映射为User对象
        modelMapper.map(model, user);
        user.setModifyTime(new Date());
        userService.updateByIdFilter(user);
        return RestResponse.ok();
    }

    // 修改用户状态（启用/禁用）
    @RequestMapping(value = "/changeStatus/{id}", method = RequestMethod.POST)
    public RestResponse<Integer> changeStatus(@PathVariable Integer id) {
        // 获取用户信息
        User user = userService.getUserById(id);
        UserStatusEnum userStatusEnum = UserStatusEnum.fromCode(user.getStatus());
        // 切换用户状态
        Integer newStatus = userStatusEnum == UserStatusEnum.Enable ? UserStatusEnum.Disable.getCode() : UserStatusEnum.Enable.getCode();
        user.setStatus(newStatus);
        user.setModifyTime(new Date());
        userService.updateByIdFilter(user);
        return RestResponse.ok(newStatus);
    }

    // 删除用户
    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
    public RestResponse delete(@PathVariable Integer id) {
        // 获取用户信息
        User user = userService.getUserById(id);
        user.setDeleted(true);
        userService.updateByIdFilter(user);
        return RestResponse.ok();
    }

    // 根据用户名查询用户
    @RequestMapping(value = "/selectByUserName", method = RequestMethod.POST)
    public RestResponse<List<KeyValue>> selectByUserName(@RequestBody String userName) {
        // 调用userService根据用户名查询用户
        List<KeyValue> keyValues = userService.selectByUserName(userName);
        return RestResponse.ok(keyValues);
    }

    /** 根据出生年月日计算年龄 */
    public static int getAgeByBirth(Date birthday){
        // 获取当前时间
        Calendar cal = Calendar.getInstance();
        // 获取出生日期的Calendar对象
        Calendar bir = Calendar.getInstance();
        bir.setTime(birthday);
        // 如果出生日期大于当前日期，则返回0
        if(cal.before(birthday)){
            return 0;
        }
        // 取出当前年月日
        int nowYear = cal.get(Calendar.YEAR);
        int nowMonth = cal.get(Calendar.MONTH);
        int nowDay = cal.get(Calendar.DAY_OF_MONTH);
        // 取出出生日期的年月日
        int birthYear = bir.get(Calendar.YEAR);
        int birthMonth = bir.get(Calendar.MONTH);
        int birthDay = bir.get(Calendar.DAY_OF_MONTH);
        // 计算年份
        int age = nowYear - birthYear;
        // 计算月份和日，看看是否大于当前月日，如果小于则减去一岁
        if(nowMonth < birthMonth || (nowMonth == birthMonth && nowDay < birthDay)){
            age--;
        }
        return age;
    }

}
